﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Obligatorio2013.Clases;
using System.Xml;
using System.Xml.Linq;
using Obligatorio2013.Logging;

namespace Obligatorio2013.Persistencia.Daos
{
    public class AdvertisementDAO : PersistentDAO
    {

        private string adFileName = "avisos.xml";


        public override bool Save(object obj)
        {
            try
            {
                if (!FileExist(adFileName))
                {
                    createFileXml(path, adFileName, "Avisos");
                }

                if (obj != null)
                {
                    // Crear un nuevo elemento 
                    Advertisement adv = obj as Advertisement;

                    XmlDocument doc = LoadXmlFile(path, adFileName);
                    XmlElement newElement = doc.CreateElement("Ad");

                    // Colocar como id un valor, por ejemplo el id del Plato - podría ser cualquier otro; esto es opcional
                    addAttribute(doc, newElement, "id", adv.id.ToString());
                    // Crear los nodos hijos.           
                    addElement(doc, newElement, "type", Enum.GetName(typeof(Advertisement.type), adv.adType));
                    addElement(doc, newElement, "title", adv.title);
                    addElement(doc, newElement, "description", adv.description);
                    addElement(doc, newElement, "price", adv.price.ToString());
                    addElement(doc, newElement, "dateFrom", adv.dateFrom.ToString());
                    addElement(doc, newElement, "dateTo", adv.dateTo.ToString());
                    addElement(doc, newElement, "phoneContact", adv.phoneContact);
                    addElement(doc, newElement, "mailContact", adv.mailContact);
                    addElement(doc, newElement, "image", adv.image);
                    addElement(doc, newElement, "suspended", Convert.ToString(adv.suspended));
                    addElement(doc, newElement, "userId", adv.publisher.UserEmail);
                    if (adv.suspended)
                    {
                        addElement(doc, newElement, "suspendedFrom", adv.dateSuspendedFrom.ToString());
                        addElement(doc, newElement, "suspendedTo", adv.dateSuspendedTo.ToString());
                    }


                    // agregar el elemento al final de la lista de elementos.
                    doc.DocumentElement.AppendChild(newElement);
                    doc.Save(path + this.adFileName);
                    return true;
                }

            }
            catch (Exception ex)
            {
                Log.Instance.Error("Error obteniendo la lista de usuarios" + ex.Message, ex);
                throw ex;
            }
            return false;
        }

        public override List<object> getAll()
        {
            XmlReader reader = XmlReader.Create(path + "\\" + adFileName);
            List<Object> ads = null;

            XElement element = XElement.Load(reader, LoadOptions.SetBaseUri);

            IEnumerable<XElement> items = element.DescendantsAndSelf("Ad");

            try
            {
                if (reader != null)
                {
                    ads = new List<Object>();

                    foreach (var xElement in items)
                    {
                        Advertisement adv = new Advertisement();
                        adv.id = long.Parse(GetAttributeValue("id", xElement));
                        string type =  GetElementValue("type", "string", xElement);
                        adv.adType = (Advertisement.type)Enum.Parse(typeof(Advertisement.type), type);

                        adv.title = GetElementValue("title", "string", xElement);
                        adv.description = GetElementValue("description", "string", xElement);
                        adv.price = Double.Parse(GetElementValue("price", "string", xElement));
                        adv.dateFrom = Convert.ToDateTime(GetElementValue("dateFrom", "string", xElement));
                        adv.dateTo = Convert.ToDateTime(GetElementValue("dateTo", "string", xElement));
                        adv.phoneContact = GetElementValue("phoneContact", "string", xElement);
                        adv.mailContact = GetElementValue("mailContact", "string", xElement);

                        adv.image = GetElementValue("image", "string", xElement);
                        adv.suspended = Boolean.Parse(GetElementValue("suspended", "string", xElement));
                        
                        Users u = new Users();
                        u.UserEmail = GetElementValue("userId", "string", xElement);
                        adv.publisher = u;

                        if (adv.suspended)
                        {
                            adv.dateSuspendedFrom = Convert.ToDateTime(GetElementValue("suspendedFrom", "string", xElement));
                            adv.dateSuspendedTo = Convert.ToDateTime(GetElementValue("suspendedTo", "string", xElement));
                        }
                        ads.Add(adv);

                    }
                }
            }
            catch (Exception ex)
            {
                Log.Instance.Error("Error cargando lista : " + ex.StackTrace);
                throw ex;
            }
            return ads;
        }

        public override bool Update(object objId)
        {
            throw new NotImplementedException();
        }

        public override bool Delete(Object obj)
        {
            try
            {
                if (FileExist(adFileName))
                {
                    Advertisement ad = obj as Advertisement;
                    XmlDocument doc = LoadXmlFile(path, adFileName);
                    XmlNode adNode = getElementByID(doc, "Ad", "id", ad.id.ToString());

                    if (adNode != null)
                    {
                        doc.RemoveChild(adNode);
                        return true;
                    }
                }
            }
            catch (Exception ex)
            {
                Log.Instance.Error("No fue posible eliminar el nodo. " + ex.Message, ex);
            }
            return false;
        }
    }
}